
// Copyright (C) 2007 Richard Uhler
// This file is part of Esiply.
//
// Esiply is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, Version 2,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include <assert.h>

#include "Boolean.h"
#include "Null.h"
#include "Object.h"
#include "Reference.h"
#include "Scope.h"
#include "String.h"

Scope::Scope(Scope* parent, Object* variable, Value* this_obj)
    : m_parent(parent), m_variable(variable), m_this(this_obj)
{}

Value* Scope::lookup(String* identifier)
{
    // Ecm 10.1.4
    // 2. Call the hasProperty method.
    // 3. If the result is true, return a reference whose base object
    // is the object, and whose property name is the identifier
    if (m_variable->hasProperty(identifier)->isTrue())
    {
        return new Reference(m_variable, identifier);
    }

    // 4. Go to step 1.
    // 1. Get the next object in the scope chain
    if (m_parent)
    {
        return m_parent->lookup(identifier);
    }

    // 5.  Return a value of type reference whose base object
    // is null, and whose property name is the identifier
    return new Reference(Null::null, identifier);
}

Value* Scope::get_this() const
{
    return m_this;
}

Object* Scope::get_variable() const
{
    return m_variable;
}

